package org.aeon.fasttasks.core.annotation;

import java.lang.annotation.Annotation;
import java.lang.reflect.Proxy;
import java.util.Map;

/**
 * @author aeon
 * @createTime 2025/08/13  17:59
 * @description 注解代理
 */
public class AnnotationProxy {

    /**
     * 传入一个 已有注解对象（annotation）和一个 覆盖 Map（attrs）。
     * 如果 Map 里有值，用 Map 的；
     * 如果 Map 没有该属性，就用原注解对象的值（再不行才用默认值）。
     *
     * @param original 原注解对象
     * @param attrs    覆盖 Map
     * @param <A>
     * @return 代理注解对象
     */
    @SuppressWarnings("unchecked")
    public static <A extends Annotation> A proxyAnnotation(A original, Map<String, Object> attrs) {

        Class<A> type = (Class<A>) original.annotationType();

        return (A) Proxy.newProxyInstance(
                type.getClassLoader(),
                new Class<?>[]{type},
                (proxy, method, args) -> {
                    String name = method.getName();

                    // 固定方法处理
                    switch (name) {
                        case "annotationType" -> {
                            return type;
                        }
                        case "toString" -> {
                            return type.getName() + attrs;
                        }
                        case "hashCode" -> {
                            return attrs.hashCode() ^ original.hashCode();
                        }
                        case "equals" -> {
                            return proxy == args[0];
                        }
                    }

                    // 优先 Map 覆盖
                    if (attrs.containsKey(name)) {
                        return attrs.get(name);
                    }

                    // 其次 原注解的值
                    Object originalValue = method.invoke(original);
                    if (originalValue != null) {
                        return originalValue;
                    }
                    // 最后 默认值
                    return method.getDefaultValue();
                }
        );
    }
}
